//
//  HttpsManager.m
//  AFNetworkingDemo
//
//  Created by MLS on 16/7/8.
//  Copyright © 2016年 MLS. All rights reserved.
//

#import "HttpRequestManager.h"
#import "UploadParam.h"

static HttpRequestManager *httpRequestManager;

@interface HttpRequestManager ()

@property (nonatomic, retain) AFHTTPSessionManager *sessionManager;

@end

@implementation HttpRequestManager

+ (HttpRequestManager *)sharedManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        httpRequestManager = [[self alloc] init];
    });
    
    return httpRequestManager;
}


/**
 *  发送get请求
 *
 *  @param URLString  请求的网址字符串
 *  @param parameters 请求的参数
 *  @param success    请求成功的回调
 *  @param failure    请求失败的回调
 */
- (void)getWithURLString:(NSString *_Nonnull)URLString
              parameters:(id _Nullable)parameters
                 success:(void (^ _Nullable)(id _Nullable responseObject))success
                 failure:(void (^ _Nullable)(NSError *_Nonnull error))failure
{
    [self.sessionManager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(error);
    }];
}


/**
 *  发送post请求
 *
 *  @param URLString  请求的网址字符串
 *  @param parameters 请求的参数
 *  @param success    请求成功的回调
 *  @param failure    请求失败的回调
 */
- (void)postWithURLString:(NSString *_Nonnull)URLString
               parameters:(id _Nonnull)parameters
                  success:(void (^ _Nullable)(id _Nullable responseObject))success
                  failure:(void (^ _Nullable)(NSError *_Nonnull error))failure
{
    [self.sessionManager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(error);
    }];
}


/**
 *  发送网络请求
 *
 *  @param URLString   请求的网址字符串
 *  @param parameters  请求的参数
 *  @param type        请求的类型
 *  @param resultBlock 请求的结果
 */
- (void)requestWithURLString:(NSString *_Nonnull)URLString
                  parameters:(id _Nullable)parameters
                        type:(HttpRequestType)type
                     success:(void (^ _Nullable)(id _Nullable responseObject))success
                     failure:(void (^ _Nullable)(NSError *_Nonnull error))failure
{
    switch (type) {
        case HttpRequestTypeGet:
        {
            [self.sessionManager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                success(responseObject);
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                failure(error);
            }];
            break;
        }
        case HttpRequestTypePost:
        {
            [self.sessionManager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                success(responseObject);
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                failure(error);
            }];
            break;
        }
        default:
            break;
    }
}


/**
 *  上传图片
 *
 *  @param URLString      地址
 *  @param parameters     参数
 *  @param uploadParamter 上传图片的一些参数
 *  @param success        上传成功回调
 *  @param failure        上传失败会掉
 */
- (void)uploadWithURLString:(NSString *_Nonnull)URLString
                 parameters:(id _Nonnull)parameters
                uploadParam:(UploadParam *_Nonnull)uploadParamter
                    success:(void (^ _Nullable)(id _Nullable responseObject))success
                    failure:(void (^ _Nullable)(NSError *_Nonnull error))failure
{
    // 创建管理者对象: self.sessionManager
    // 参数
    
    [self.sessionManager POST:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        // 拼接数据到请求题中
        [formData appendPartWithFileData:uploadParamter.data name:uploadParamter.name fileName:uploadParamter.fileName mimeType:uploadParamter.mimeType];
        /******** 2.通过路径上传沙盒或系统相册里的图片 *****/
        //        [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"文件地址"] name:@"file" fileName:@"1234.png" mimeType:@"application/octet-stream" error:nil];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        // 打印上传进度
        NSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success(responseObject);
        //请求成功
        NSLog(@"请求成功：%@",responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(error);
        //请求失败
        NSLog(@"请求失败：%@",error);
    }];
}


/**
 *  down
 *
 *  @param urlString 地址
 */
- (void)downLoadWithUrlString:(NSString *)urlString
{
    
    // 1.创建管理者对象: self.sessionManager
    // 2.设置请求的URL地址
    NSURL *url = [NSURL URLWithString:urlString];
    // 3.创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 4.下载任务
    NSURLSessionDownloadTask *task = [self.sessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        // 下载进度
        NSLog(@"当前下载进度为:%lf", 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        // 下载地址
        NSLog(@"默认下载地址%@",targetPath);
        // 设置下载路径,通过沙盒获取缓存地址,最后返回NSURL对象
        NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
        return [NSURL fileURLWithPath:filePath]; // 返回的是文件存放在本地沙盒的地址
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        // 下载完成调用的方法
        NSLog(@"%@---%@", response, filePath);
    }];
    // 5.启动下载任务
    [task resume];
}

/**
 *  取消请求当前所有网络请求
 */

- (void)cancelAllOperations
{
    [self.sessionManager.operationQueue cancelAllOperations];
}

/**
 *  监听网络状态
 */
- (void)AFNetworkStatus
{
    
    //1.创建网络监测者
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    
    /*枚举里面四个状态  分别对应 未知 无网络 数据 WiFi
     typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
     AFNetworkReachabilityStatusUnknown          = -1,      未知
     AFNetworkReachabilityStatusNotReachable     = 0,       无网络
     AFNetworkReachabilityStatusReachableViaWWAN = 1,       蜂窝数据网络
     AFNetworkReachabilityStatusReachableViaWiFi = 2,       WiFi
     };
     */
    
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        //这里是监测到网络改变的block  可以写成switch方便
        //在里面可以随便写事件
        switch (status)
        {
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"未知网络状态");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"无网络");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"蜂窝数据网");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WiFi网络");
                
                break;
                
            default:
                break;
        }
        
    }] ;  
}


#pragma mark - 懒加载管理者对象

- (AFHTTPSessionManager *)sessionManager
{
    if (!_sessionManager)
    {
        _sessionManager = [AFHTTPSessionManager manager];
        // 超时时间
        _sessionManager.requestSerializer.timeoutInterval = 10;
        
        // 声明上传的是json格式的参数，需要你和后台约定好，不然会出现后台无法获取到你上传的参数问题
        _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer]; // 上传普通格式
        //    _sessionManager.requestSerializer = [AFJSONRequestSerializer serializer]; // 上传JSON格式
        
        // 声明获取到的数据格式/类型
        _sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; // AFN不会解析,数据是data，需要自己解析
        //    _sessionManager.responseSerializer = [AFJSONResponseSerializer serializer]; // AFN会JSON解析返回的数据
        /*个人建议还是自己解析的比较好，有时接口返回的数据不合格会报3840错误，大致是AFN无法解析返回来的数据*/
        
        // 请求队列的最大并发数
        //    _sessionManager.operationQueue.maxConcurrentOperationCount = 5;
        // 请求超时的时间
        //    _sessionManager.requestSerializer.timeoutInterval = 5;
        
    }
    
    return _sessionManager;
}

@end
